package com.example.theoretical_verification.thread;

import java.util.concurrent.atomic.AtomicInteger;

// 这个例子没有用ThreadLocal，实际打印是有问题的哦。每次重新运行的打印的结果都不太一样。并且有时候有-1和null，有时候又没有。
// 这个是把userInfo定义在测试类里面，作为全局变量。如果是用全局变量的话，就要注意线程安全的问题。本例子中run那部分的逻辑没有加synchronize代码块，所以实际打印就会有同步问题。
public class ThreadLocalExample02 {

    // 定义一个ThreadLocal对象来存储用户信息
    private static UserInfo userInfo = new UserInfo();

    // AtomicInteger用于生成用户ID
    private static AtomicInteger nextUserId = new AtomicInteger(1);

    // 用户信息类
    static class UserInfo {
        private int userId;
        private String username;

        public UserInfo() {
        }

        public UserInfo(String username) {
            this.userId = nextUserId.getAndIncrement();
            this.username = username;
        }

        public int getUserId() {
            return userId;
        }

        public String getUsername() {
            return username;
        }

        public void setUserId(int userId) {
            this.userId = userId;
        }

        public void setUsername(String username) {
            this.username = username;
        }
    }

    public static void main(String[] args) {
        // 模拟多个线程访问应用，每个线程都设置自己的用户信息
        for (int i = 0; i < 20; i++) {
            final int userId = i;
            new Thread(() -> {

                // 设置当前线程的用户信息
                userInfo.setUserId(userId);
                userInfo.setUsername("User_" + userId);
                System.out.println("Thread " + Thread.currentThread().getId() +
                        " - User ID: " + userInfo.getUserId() +
                        ", Username: " + userInfo.getUsername());
                // 清除当前线程的用户信息
                userInfo.setUserId(-1);
                userInfo.setUsername(null);
            }).start();
        }
    }
}

